<?php

declare(strict_types=1);

namespace App\Service;

use App\Common\Tools\DbTools;
use App\Constants\ErrorCode;
use App\Exception\BusinessException;
use App\Library\Common;
use App\Model\FlyOrderProduct;
use App\Model\FlyShopDelivery;
use App\Model\Moment;
use Hyperf\Database\Model\Builder;
use Hyperf\DbConnection\Db;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\Snowflake\IdGeneratorInterface;
use Hyperf\Utils\ApplicationContext;
use Hyperf\Validation\Contract\ValidatorFactoryInterface;
use Hyperf\Di\Annotation\Inject;
use Hyperf\Validation\Rule;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Yansongda\Supports\Collection;

/**
 * 商城订单服务
 * Class FlyOrderService
 * @package App\Service
 */
class FlyOrderService extends BaseService
{

    const STYLE_SHOP = 1;// 商城订单
    const STYLE_SEAT = 2;// 订座订单
    const STYLE_ORDER = 3;// 点餐订单

    /**
     * @Inject appUser
     * @var AppUserService
     */
    private $appUser;

    /**
     * @Inject
     * @var OrderCouponService
     */
    private $orderCoupon;

    /**
     * @Inject
     * @var DeliveryRuleService
     */
    private $rule;

    /**
     * @Inject
     * @var DeliveryRuleAreaService
     */
    private $deliveryRuleArea;

    /**
     * @Inject
     * @var DeliveryTplService
     */
    private $tpl;

    // 待付款
    const STATUS_WAIT_PAY = 1;
    // 待收货
    const STATUS_WAIT_RECEIVE = 2;
    // 已完成
    const STATUS_FINISHED = 3;
    // 已取消
    const STATUS_CLOSED = 4;

    const CHARGE_TYPE_SCAN = 1;
    const CHARGE_TYPE_CODE = 2;
    const CHARGE_TYPE_CLICK = 3;

    /**
     * @Inject
     * @var ShopDeliveryConfigService
     */
    private $deliveryConfig;

    /**
     * @Inject
     * @var DeliveryRuleAreaService
     */
    private $tplArea;

    /**
     * @Inject
     * @var OrderDeliveryService
     */
    private $orderDelivery;

    /**
     * @Inject
     * @var AftersaleSetService
     */
    private $reasonSet;

    /**
     * @Inject
     * @var PayService
     */
    private $payService;

    /**
     * @Inject
     * @var SkuService
     */
    private $sku;

    /**
     * @Inject
     * @var FlyPayOrderService
     */
    private $flyPayOrder;

    /**
     * @Inject
     * @var FlyOrderProductService
     */
    private $flyOrderProduct;

    /**
     * @Inject
     * @var FlyAddressService
     */
    private $address;

    /**
     * @Inject
     * @var FlyCartService
     */
    private $cart;

    /**
     * @Inject
     * @var RequestInterface
     */
    private $request;

    /**
     * @Inject
     * @var ValidatorFactoryInterface
     */
    private $validationFactory;

    /**
     * [
     *    pay_order_data => [],
     *    shop_order_data => [
     *       [shop_id] => [
     *              order_info => [],
     *              product_info => []
     *        ]
     *    ]
     * ]
     * 验证并返回有效数据
     * @param int $user_id
     * @param bool $is_commit 是否提交订单
     * @return array
     */
    public function createVerify(int $user_id, bool $is_commit = true): array
    {
        $return = [
            'res' => true,
            'msg' => "",
            'data' => []
        ];


        $params = $this->request->all();
        $verify_res = $this->validationFactory->make($params,
            [
                "address_id" => ['nullable', 'integer'], // 收货地址ID
                "delivery_type" => ['nullable', Rule::in([ShopDeliveryConfigService::TYPE_EXPRESS, ShopDeliveryConfigService::TYPE_OWN, ShopDeliveryConfigService::TYPE_LOCAL, ShopDeliveryConfigService::TYPE_VIRTUAL])],
                "products.*.sku_id" => ['integer', 'nullable'], // 直接下单
                "products.*.quantity" => ['integer', 'min:0', 'nullable'],
                'user_lat' => ['nullable', 'numeric'],
                'user_lng' => ['nullable', 'numeric'],
            ], [
                'delivery_type.integer' => '收货地址错误',
                'quantity.integer' => '购买数量必须为有效整数',
                'quantity.min' => '数量至少1个']);
        if ($verify_res->fails()) {
            $return['res'] = false;
            $return['msg'] = $verify_res->errors()->first();
            return $return;
        }
        $remarks = $params['remarks'] ?? [];
        $coupon_id = [];
        if (!empty($remarks)) {
            $remarks = array_column($remarks, 'remark', 'shop_id');
            $date_time = array_column($params['remarks'], 'date_time', 'shop_id');
            $coupon_id = array_column($params['remarks'], 'coupon_id', 'shop_id');
        }
        $params['delivery_type'] = empty($params['delivery_type']) ? ShopDeliveryConfigService::TYPE_VIRTUAL : $params['delivery_type'];
        // 配送和物流必须提供收货地址
        if (in_array($params['delivery_type'], [ShopDeliveryConfigService::TYPE_EXPRESS, ShopDeliveryConfigService::TYPE_LOCAL]) && empty($params['address_id'])) {
            throw new BusinessException(ErrorCode::NORMAL_ERROR, '定位获取失败');
        }
        if ($params['delivery_type'] != ShopDeliveryConfigService::TYPE_VIRTUAL) {
            // 非自提 且非虚拟产品  需要提供收货地址
            if ($params['delivery_type'] != ShopDeliveryConfigService::TYPE_OWN) {
                if (empty($params['address_id'])) {
                    throw new BusinessException(ErrorCode::NORMAL_ERROR, '未填写收货地址');
                }
                // 收货地址
                $address = $this->address->getMyAddressById($user_id, $params['address_id']);
                if (empty($address)) {
                    $return['res'] = false;
                    $return['msg'] = "收货地址无效";
                    return $return;
                }
            } else {
                // 自提订单：根据ip获取定位
                if (empty($params['user_lat']) || empty($params['user_lng'])) {
                    // 根据收货地址获取经纬度
                    if (!empty($params['address_id'])) {
                        $address = $this->address->getMyAddressById($user_id, $params['address_id']);
                        if (empty($address)) {
                            throw new BusinessException(ErrorCode::NORMAL_ERROR, '收货地址无效');
                        }
                        $street_arr = array_column(make(AreainfoService::class)->getFullAddress($address['street_id']), 'name');
                        $address_str = implode('', $street_arr);
                    } else {
                        // 根据ip所在城市获取经纬度
                        $ip = make(MomentService::class)->getRealIp();
                        $address_str = Common::getLocateByIp($ip);// 根据IP定位城市
                    }

                    $locate = Common::getAddressLocation($address_str);
                    $params['user_lat'] = empty($locate['lat']) ? 0 : floatval($locate['lat']);
                    $params['user_lng'] = empty($locate['lng']) ? 0 : floatval($locate['lng']);
                }
                $address = [];
            }
        }

        // 结算购物车选中商品
        $sku_count = 0;
        if (empty($params['products'])) {
            /****************************** 验证购物车商品有效性 start ******************************/
            $cart = $this->cart->getCartSku($user_id);
            $cart_arr = $cart['data'];
            /****************************** 验证购物车商品有效性 end ******************************/
        } else {
            if (empty($params['products'])) {
                throw new BusinessException(ErrorCode::NORMAL_ERROR, '未选择数量');
            }
            // 构造相同结构订单信息
            $new_p = [];
            foreach ($params['products'] as &$buy_p) {
                if (empty($buy_p['quantity']) || empty($buy_p['sku_id'])) {
                    throw new BusinessException(ErrorCode::NORMAL_ERROR, '缺少参数');
                }
                $buy_p['id'] = 0;
                $new_p[$buy_p['sku_id']] = $buy_p;
            }
            $cart_arr = $this->cart->showByShop($new_p, false);// 非真实从购物车结算
            $sku_count = count($new_p);// sku种类数
        }

        $moments_id = empty($params['moments_id']) ? 0 : (int)$params['moments_id'];
        if (!empty($moments_id)) {
            if (empty($params['products']) || count($params['products']) > 1) {
                throw new BusinessException(ErrorCode::NORMAL_ERROR, '无效操作');
            }
        }

        $product = []; // 有效商品数组
        $tmp_vir_info = [];
        foreach ($cart_arr as $shop) {
            // 拆分归类商品（todo: 根据商家模板单独计算运费
            foreach ($shop['carts'] as $cart) {
                if (empty($cart['sku_info']['with_product'])) {
                    continue;
                }
                // 需结算的商品
                if (!empty($params['products']) || $cart['is_selected'] == 1) {
                    if ($cart['sku_info']['with_product']['industry_info']['is_unreal'] == 1) {
                        if ($sku_count > 1) {
                            throw new BusinessException(ErrorCode::NORMAL_ERROR, '虚拟产品不支持多商品批量购买');
                        }
                        $cart['sku_info']['is_valid'] = 1;//虚拟商品有效
                        // 虚拟产品--验证表单字段
                        if (!empty($cart['sku_info']['with_product']['industry_info']['with_virtual_params'])) {
                            $v_params_arr = json_decode($cart['sku_info']['with_product']['industry_info']['with_virtual_params']['json_form'], true);
                            if (!empty($v_params_arr)) {
                                foreach ($v_params_arr as $value) {
                                    if (1 == $value['is_must']) {
                                        // 表单配置不完整
                                        if (in_array($value['type'], [2, 3]) && empty($value['check_box'])) {
                                            $cart['sku_info']['is_valid'] = 0;
                                        }
                                        if ($is_commit && $value['is_must'] == 1 && empty($params['virtual_params'][$value['code']])) {
                                            throw new BusinessException(ErrorCode::NORMAL_ERROR, '缺少必填参数' . $value['code']);
                                        }
                                    }
                                    // 多选
                                    if (3 == $value['type']) {
                                        foreach ($params['virtual_params'][$value['code']] as $vv) {
                                            if (isset($params['virtual_params']) && !in_array($vv, $value['check_box'])) {
                                                throw new BusinessException(ErrorCode::NORMAL_ERROR, $value['code'] . ':参数不合法1');
                                            }
                                        }
                                    } elseif (2 == $value['type']) {
                                        // 单选
                                        if (isset($params['virtual_params']) && !in_array($params['virtual_params'][$value['code']], $value['check_box'])) {
                                            throw new BusinessException(ErrorCode::NORMAL_ERROR, $value['code'] . '参数不合法2');
                                        }
                                    }
                                    $tmp_vir_info[$value['code']] = [
                                        'name' => $value['code_name'],
                                        'value' => !isset($params['virtual_params']) ? "" : $params['virtual_params'][$value['code']]
                                    ];
                                }
                            }
                        }
                        $params['is_virtual'] = 1;
                    } else {
                        // 商品无效
                        if (!empty($cart['sku_info']['with_product']) &&
                            $cart['sku_info']['with_product']['is_illegal'] == 0 &&
                            $cart['sku_info']['with_product']['check_status'] == 1 &&
                            $cart['sku_info']['with_product']['is_show'] == 1) { // 未配置运费模板（或商品本不应该展示此时下单则为违规商品：提示无货）
                            if (!empty($params['delivery_type']) && $params['delivery_type'] == ShopDeliveryConfigService::TYPE_EXPRESS) {
                                if (empty($cart['sku_info']['with_product']['delivery_id'])) {
                                    // 未配置运费模板
                                    $cart['sku_info']['is_valid'] = 0;
                                } else {
                                    // 商品配置运费模板判断（配送方式为物流时）
                                    $cart['sku_info']['with_product']['tpl'] = $this->tpl->getTplById($cart['sku_info']['with_product']['delivery_id'], $cart['sku_info']['with_product']['shop_id']);
                                    if (empty($cart['sku_info']['with_product']['tpl'])) {
                                        // 运费模板配置无效
                                        $cart['sku_info']['is_valid'] = 0;
                                    } else {
                                        if ($cart['sku_info']['with_product']['tpl']['is_all_area'] == 1) {
                                            $cart['sku_info']['with_product']['rule'] = $cart['sku_info']['with_product']['tpl']['rules'][0] ?? [];
                                        } else {
                                            $rule_id = $this->deliveryRuleArea->getRulesIdByPCS($cart['sku_info']['with_product']['delivery_id'], $address['address_arr'][0]['id'], $address['address_arr'][1]['id'], $address['address_arr'][2]['id']);
                                            $cart['sku_info']['with_product']['rule'] = $this->rule->getRuleById($rule_id);
                                        }
                                        $cart['sku_info']['is_valid'] = 1;
                                    }
                                }
                            } else {
                                $cart['sku_info']['is_valid'] = 1;
                            }
                        } else {
                            // 商品无效
                            $cart['sku_info']['is_valid'] = 0;
                        }
                    }

                    // 判断是否为达人分销商品
                    if (!empty($data['moments_id'])) {
                        $product_id = $cart['sku_info']['with_product']['id'];
                        // 为分销下单-为分销成功用户提成
                        $moment_info = make(Moment::class)
                            ->where(['id' => $moments_id])
                            ->whereHas('with_valid_dr', function ($where) use ($product_id) {
                                $where->where('product_id', $product_id);
                            })->first();
                        // 分销有效
                        if (!empty($moment_info) && !empty($moment_info->with_valid_dr) && !empty($moment_info->with_valid_dr->with_shop_ad)) {
                            $cart['sku_info']['moments_id'] = $moments_id;
                        }
                    }// 购物车下单自动将达人圈分销商品下单时保存，在支付时判断是否有效

                    // 商品图
                    $cart['sku_info']['sku_img'] = "";
                    if (!empty($cart['sku_info']['file_info'])) {
                        $cart['sku_info']['sku_img'] = $cart['sku_info']['file_info']['url'];
                    } else {
                        if (!empty($cart['sku_info']['with_product']['main_pic'])) {
                            foreach ($cart['sku_info']['with_product']['main_pic'] as $pic) {
                                if ($pic['file_info']['imagetype'] != 'mp4') {
                                    $cart['sku_info']['sku_img'] = $pic['file_info']['url'];
                                    break;
                                }
                            }
                        }
                    }
                    $cart['sku_info']['shop_tag'] = $cart['sku_info']['with_product']['with_shop']['type'] == 3 ? "制造商" : "商家";
                    $cart['sku_info']['shop_join_dc'] = $cart['sku_info']['with_product']['with_shop']['with_join_dc']['name'] ?? "";
                    $cart['sku_info']['delivery_id'] = $cart['sku_info']['with_product']['delivery_id'];// 运费模板ID
                    $cart['sku_info']['quantity'] = $cart['quantity'];
                    $cart['sku_info']['cart_id'] = $cart['id'];
                    $cart['sku_info']['landmark'] = $cart['landmark'] ?? "";
                    $product[] = $cart['sku_info'];
                }
            }
        }

        // 支付单模板
        $pay_order_data = [
            'delivery_price' => 0,// 运费金额
            'coupon_price' => 0,// 优惠券金额
            'pay_price' => 0, // 应支付金额
            'pay_order_sn' => $is_commit ? $this->generateOrderSn('P') : "",
            'product_price' => 0,// 商品金额
            'user_id' => $user_id,
            'is_virtual' => $params['is_virtual'] ?? 0,
        ];
        // 商家订单模板
        $public_order_data = [
            'order_sn' => "",
            'order_price' => 0,
            'pay_price' => 0,
            'product_num' => 0,
            'product_price' => 0,
            'user_id' => $user_id,
            'link_name' => $address['link_name'] ?? "",
            'address' => ($address['street_str'] ?? "") . ($address['address_info'] ?? ""),
            'phone' => !empty($address['phone']) ? $address['phone'] : ($this->appUser->getUserInfo($user_id))['username'] ?? "",
            'address_id' => $address['id'] ?? 0,
            'pay_order_sn' => $pay_order_data['pay_order_sn'],// 支付单号
            'shop_id' => 0,
            'pay_order_id' => 0,
            'create_time' => time(),
            'coupon_id' => 0,
            'remark' => '',
            'coupon_price' => 0,
            'express_tpl_id' => 0,
            'delivery_price' => 0,
            'is_virtual' => $params['is_virtual'] ?? 0,
            'virtual_form_info' => json_encode($tmp_vir_info),
            'virtual_form_arr' => $v_params_arr ?? [],
            'virtual_params' => $params['virtual_params'] ?? [],
            'shop_coupons' => [],// 已领取店铺优惠券
            'selected_coupon' => [],// 当前使用的优惠券
        ];
        $order = [];
        // 订单相关计算--涉及金额按整数“分”进行计算
        foreach ($product as $p) {
            if ($is_commit && $p['is_valid'] == 0) {
                continue;// 下单无效商品不算入订单
            }
            // $p = carts
            $price = floatval($p['step_price']);
            if (!isset($order[$p['with_product']['shop_id']])) {
                $public_order_data['shop_id'] = $p['with_product']['shop_id'];
                $shop_delivery_type = $this->deliveryConfig->getDeliveryConfigByShop($public_order_data['shop_id']);
                $delivery_valid = 1;// 默认有效
                $local_delivery_valid = 1; // 默认不超出配送范围
                $take_time_start = 0;
                $take_time_end = 0;
                // 收货距离
                $distance = 0.00;
                $delivery_id = 0;

                if (empty($params['is_virtual'])) {
                    if (empty($shop_delivery_type) || !in_array($params['delivery_type'], array_column($shop_delivery_type, 'delivery_type'))) {
                        $delivery_valid = 0;// 未配置
                    } else {
                        foreach ($shop_delivery_type as $k => $d_type) {
                            // 判断配置是否开启
                            if ($d_type['delivery_type'] == $params['delivery_type']) {
                                $delivery_id = $d_type['id'];
                                if ($d_type['config_status'] == 0) {
                                    $delivery_valid = 0;
                                }
                            }
                            // 同城配送范围判断
                            if (!empty($d_type['delivery_type']) && $d_type['delivery_type'] == ShopDeliveryConfigService::TYPE_LOCAL && $params['delivery_type'] == ShopDeliveryConfigService::TYPE_LOCAL) {
                                $distance = DbTools::getPointDistance($address['lng'], $address['lat'], $p['with_product']['with_shop']['lng'], $p['with_product']['with_shop']['lat']);
                                if (false === $distance) {
                                    throw new BusinessException(ErrorCode::NORMAL_ERROR, '未获取到位置信息');
                                }
                                // 超出配送范围
                                if ($distance > $d_type['max_range']) {
                                    $local_delivery_valid = 0;
                                }
                                $take_time_start = $d_type['start_time'];
                                $take_time_end = $d_type['end_time'];
                            } elseif (!empty($d_type['delivery_type']) && $d_type['delivery_type'] == ShopDeliveryConfigService::TYPE_OWN) {
                                $distance = DbTools::getPointDistance($params['user_lng'] ?? 0, $params['user_lat'] ?? 0, $p['with_product']['with_shop']['lng'], $p['with_product']['with_shop']['lat']);
                                $take_time_start = $d_type['start_time'];
                                $take_time_end = $d_type['end_time'];
                            }
                        }
                    }

                }

                $order[$p['with_product']['shop_id']] = [
                    'shop_id' => $p['with_product']['shop_id'],
                    'shop_name' => $p['with_product']['with_shop']['shop_name'] ?? "",
                    'phone' => $p['with_product']['with_shop']['phone'] ?? "",
                    'start_time' => $take_time_start,
                    'end_time' => $take_time_end,
                    'order_info' => $public_order_data,// 按店铺拆分订单
                    'date_time' => isset($date_time) ? ($date_time[$p['with_product']['shop_id']] ?? 0) : 0,// 提货时间
                    'delivery_distance' => $distance,// 提货、配送距离
                    'delivery_valid' => $delivery_valid,// 店铺规则是否有效
                    'local_delivery_valid' => $local_delivery_valid,// 当地配送是否有效
                    'delivery_types' => $shop_delivery_type,// 店铺支持的运费规则
                    'delivery_type' => $params['delivery_type'] ?? 0,// 用户收货方式
                    'delivery_config_id' => $delivery_id,
                    'product_info' => [] // 按店铺拆分商品
                ];
            }
            $subtotal = Common::yuan2fen($price) * $p['quantity'];

            // todo 计算优惠券邮费
            $order[$p['with_product']['shop_id']]['product_info'][] = [
                'is_valid' => $p['is_valid'],// 未配置快递（选择配送方式为物流时）
                'delivery_valid' => $order[$p['with_product']['shop_id']]['delivery_valid'],// 未配置配送（当配送方式为同城配送时）
                'local_delivery_valid' => $order[$p['with_product']['shop_id']]['local_delivery_valid'],// 配送超距（当配送方式为同城时）
                'cart_id' => $p['cart_id'] ?? 0,
                'order_id' => 0,
                'sku_id' => $p['sku_id'],
                'sku_name' => $p['sku_name'],
                'product_id' => $p['product_id'],
                'product_name' => $p['with_product']['product_name'],
                'single_price' => $price, // sku单价
                'quantity' => $p['quantity'],
                'subtotal' => $is_commit ? $subtotal : Common::fen2yuan($subtotal), // int
                'sku_img' => $p['sku_img'],
                'weight' => $p['weight'] ?: 0,// 单个sku重量
                'volume' => $p['volume'] ?: 0, // 单个sku体积
                'tpl_id' => $p['with_product']['delivery_id'] ?? 0,
                'landmark' => $p['landmark'] ?? "",
                'shop_tag' => $p['shop_tag'] ?? "",
                'shop_join_dc' => $p['shop_join_dc'],
                'dc_id' => $p['with_product']['with_shop']['with_join_dc']['id'] ?? 0,
                'dc_name' => $p['shop_join_dc'],
                'industry_id' => $p['with_product']['industry_info']['id'] ?? 0,
                'industry_name' => $p['with_product']['industry_info']['industry_name'] ?? "",
                'min_quantity' => $p['with_product']['min_quantity'] ?? 0,
                'delivery_id' => $p['with_product']['delivery_id'],
                'tpl' => $p['with_product']['tpl'] ?? [],
                'rule' => $p['with_product']['rule'] ?? [],
                'is_step_price' => (int)$p['is_step_price'],// 是否阶梯价
                'is_virtual' => $params['is_virtual'] ?? 0, // 是否为虚拟产品
                'moments_id' => $p['moments_id'] ?? 0
            ];
            // 对有效商品进行金额统计(开启配置+（物流商品配置运费模板 或 配送在有效范围 或 用户自提）)
            if ((!empty($params['is_virtual']) && 1 == $params['is_virtual']) || ($order[$p['with_product']['shop_id']]['delivery_valid'] == 1 &&
                    (($params['delivery_type'] == ShopDeliveryConfigService::TYPE_EXPRESS && $p['is_valid'] == 1) ||
                        ($params['delivery_type'] == ShopDeliveryConfigService::TYPE_LOCAL && ($order[$p['with_product']['shop_id']]['delivery_valid'] == 1 &&
                                $order[$p['with_product']['shop_id']]['local_delivery_valid'] == 1))
                        || $params['delivery_type'] == ShopDeliveryConfigService::TYPE_OWN))) {
                // 商家订单参数补充
                $order[$p['with_product']['shop_id']]['order_info']['order_price'] += $subtotal; // 转换为整数金额计算
                $order[$p['with_product']['shop_id']]['order_info']['pay_price'] += $subtotal; // 转换为整数金额计算
                $order[$p['with_product']['shop_id']]['order_info']['product_num'] += $p['quantity'];
                $order[$p['with_product']['shop_id']]['order_info']['product_price'] += $subtotal;// 商品金额
                // 支付单支付金额计算
                $pay_order_data['pay_price'] += $subtotal;
                $pay_order_data['product_price'] += $subtotal;
            }
        }
        $pay_order_data['pay_price'] = $is_commit ? $pay_order_data['pay_price'] : Common::fen2yuan($pay_order_data['pay_price']);
        $pay_order_data['product_price'] = $is_commit ? $pay_order_data['product_price'] : Common::fen2yuan($pay_order_data['product_price']);
        // 配送类型
        $pay_order_data['delivery_type'] = $params['delivery_type'] ?? 0;
        if (!$is_commit) {
            foreach ($order as &$item) {
                $item['order_info']['date_time'] = $date_time[$item['order_info']['shop_id']] ?? 0;
                $item['order_info']['remark'] = $remarks[$item['order_info']['shop_id']] ?? "";
                // coupon_price - 优惠券金额 | express_price - 运费金额
                $item['order_info']['order_price'] = Common::fen2yuan($item['order_info']['order_price']);
                $item['order_info']['pay_price'] = Common::fen2yuan($item['order_info']['pay_price']);
                $item['order_info']['product_price'] = Common::fen2yuan($item['order_info']['product_price']);
            }
        } else {
            foreach ($order as &$item) {
                $item['order_info']['remark'] = $remarks[$item['shop_id']] ?? "";
                // coupon_price - 优惠券金额 | express_price - 运费金额
            }
        }
        $order_data = [
            'pay_order_data' => $pay_order_data,
            'shop_order_data' => array_merge($order),
            'address_info' => $address ?? []
        ];
        if (empty($params['is_virtual'])) {
            // 计算各店铺运费
            $delivery_res = $this->orderDelivery->calculatePrice($order_data, $is_commit, (int)$params['delivery_type']);
            if (!$delivery_res) {
                $return['msg'] = "运费计算失败";
                $return['res'] = false;
            }
        }

        $coupon_total = 0;
        foreach ($order_data['shop_order_data'] as &$shop_coupon_v) {
            // 店铺优惠券
            $shop_coupon_v['order_info']['coupon_price'] = 0;
            if (!empty($coupon_id[$shop_coupon_v['shop_id']])) {
                $coupon_res = $this->orderCoupon->verifyOrderCoupon($user_id, $coupon_id[$shop_coupon_v['shop_id']], $shop_coupon_v['shop_id'], $shop_coupon_v['product_info']);
                if (!empty($coupon_res['can_use'])) {
                    $shop_coupon_v['order_info']['coupon_price'] = $coupon_res['coupon_price'];
                    $shop_coupon_v['order_info']['selected_coupon'] = $coupon_res['coupon'];
                }
            }

            // 总订单优惠券
            $order_data['pay_order_data']['coupon_price'] += $shop_coupon_v['order_info']['coupon_price'];
            $coupon_total += $shop_coupon_v['order_info']['coupon_price'];
            if (!$is_commit) {
                $shop_coupon_v['order_info']['coupon_price'] = Common::fen2yuan($shop_coupon_v['order_info']['coupon_price']);
            }

            if (!$is_commit) {
                $order_data['pay_order_data']['pay_price'] = Common::fen2yuan(Common::yuan2fen($order_data['pay_order_data']['pay_price']) - $coupon_total);
                $order_data['pay_order_data']['coupon_price'] = Common::fen2yuan($coupon_total);
            } else {
                $order_data['pay_order_data']['pay_price'] = $order_data['pay_order_data']['pay_price'] - $coupon_total;
                $order_data['pay_order_data']['coupon_price'] = $coupon_total;
            }
        }
        $return['data'] = $order_data;
        return $return;
    }

    /**
     * 创建用户订单：返回支付单ID
     * @param array $orderData
     * @param bool $return_sn
     * @return int | string
     */
    public function createOrder(array $orderData, ?bool $return_sn = false)
    {

        Db::beginTransaction();
        try {
            // 创建支付单
            $orderData['pay_order_data']['pay_price'] = Common::fen2yuan($orderData['pay_order_data']['pay_price']);
            $orderData['pay_order_data']['product_price'] = Common::fen2yuan($orderData['pay_order_data']['product_price']);
            $orderData['pay_order_data']['delivery_price'] = Common::fen2yuan($orderData['pay_order_data']['delivery_price']);
            $orderData['pay_order_data']['coupon_price'] = Common::fen2yuan($orderData['pay_order_data']['coupon_price']);
            $pay_order_id = $this->flyPayOrder->createOrder($orderData['pay_order_data']);
            if (empty($pay_order_id)) {
                Db::rollBack();
                throw new BusinessException(ErrorCode::NORMAL_ERROR, '支付单生成失败:' . json_encode($orderData['pay_order_data']));
            }
            // 订单
            // 清除购物车已购买商品
            $cart_ids = [];
            foreach ($orderData['shop_order_data'] as $shop_id => &$datum) {
                if (empty($datum['product_info'])) {
                    Db::rollBack();
                    throw new BusinessException(ErrorCode::NORMAL_ERROR, '无有效商品');
                }

                $datum['order_info']['order_sn'] = $this->generateOrderSn();
                $datum['order_info']['shop_name'] = $datum['shop_name'];
                $datum['order_info']['pay_order_id'] = $pay_order_id;
                $datum['order_info']['order_price'] = Common::fen2yuan($datum['order_info']['order_price']);
                $datum['order_info']['pay_price'] = Common::fen2yuan($datum['order_info']['pay_price']) + Common::fen2yuan($datum['order_info']['delivery_price']) - Common::fen2yuan($datum['order_info']['coupon_price']);
                $datum['order_info']['product_price'] = Common::fen2yuan($datum['order_info']['product_price']);
                $datum['order_info']['delivery_price'] = Common::fen2yuan($datum['order_info']['delivery_price']);
                $datum['order_info']['coupon_price'] = Common::fen2yuan($datum['order_info']['coupon_price']);
                $datum['order_info']['order_status'] = self::STATUS_WAIT_PAY;// 待付款
                $datum['order_info']['delivery_type'] = $datum['delivery_type'];// 配送方式
                $datum['order_info']['charge_off_code'] = $datum['delivery_type'] == ShopDeliveryConfigService::TYPE_OWN ? rand(100000, 999999) : "";
                $datum['order_info']['delivery_distance'] = $datum['delivery_distance'] ?? 0.00;
                $datum['order_info']['delivery_config_id'] = $datum['delivery_config_id'] ?? 0;
                $datum['order_info']['date_time'] = $datum['date_time'] ?? 0;
                // 无有效商品
                if (empty($datum['order_info']['pay_price'])) {
                    continue;
                }
                // 保存店铺订单
                foreach ($datum['order_info'] as $k => $value) {
                    if (is_array($value)) {
                        unset($datum['order_info'][$k]);
                    }
                }
                $order_id = $this->getModelInstance()->insertGetId($datum['order_info']);
                if (empty($order_id)) {
                    Db::rollBack();
                    throw new BusinessException(ErrorCode::NORMAL_ERROR, '商家订单生成失败：' . json_encode($datum['order_info']));
                }
                // 扣除优惠券
                if ($datum['order_info']['coupon_id'] > 0 && !$this->orderCoupon->useUserCoupon($datum['order_info']['user_id'], $datum['order_info']['coupon_id'], $order_id)) {
                    Db::rollBack();
                    throw new BusinessException(ErrorCode::NORMAL_ERROR, '优惠券操作失败');
                }

                // 保存店铺订单商品
                foreach ($datum['product_info'] as $k => &$item) {
                    // 无效商品
                    if (empty($item['is_valid']) || empty($item['delivery_valid']) || empty($item['local_delivery_valid'])) {
                        unset($datum['product_info'][$k]);
                        continue;
                    }
                    // 购物车结算-清除下单后的购物车商品
                    if (!empty($item['cart_id'])) {
                        $cart_ids[] = $item['cart_id'];
                    }
                    unset($item['cart_id'], $item['is_valid'], $item['delivery_valid'], $item['local_delivery_valid']);
                    $item['order_id'] = $order_id;
                    $item['pay_order_id'] = $pay_order_id;
                    $item['subtotal'] = Common::fen2yuan($item['subtotal']);
                }
                $product_res = $this->flyOrderProduct->saveOrderProduct($datum['product_info']);
                if (!$product_res) {
                    Db::rollBack();
                    throw new BusinessException(ErrorCode::NORMAL_ERROR, '商家订单商品保存失败:' . json_encode($datum['product_info']));
                }
            }
            // todo 本地测试不清购物车
            if (!empty($cart_ids)) {
                // 清空已结算购物车商品
                $res = $this->cart->delCart($orderData['user_id'], $cart_ids, 2);
                if (!$res) {
                    Db::rollBack();
                    throw new BusinessException(ErrorCode::NORMAL_ERROR, '清空购物车失败:' . json_encode($cart_ids));
                }
            }
        } catch (\Throwable $exception) {
            echo $exception->getMessage();
            Db::rollBack();
            throw new BusinessException(ErrorCode::NORMAL_ERROR, '生成失败：' . $exception->getMessage());
        }
        Db::commit();
        // 返回支付单号或支付单ID
        return $return_sn ? $orderData['pay_order_data']['pay_order_sn'] : $pay_order_id;
    }


    /**
     * 生成订单号
     * @param string $prefix
     * @return string
     */
    public function generateOrderSn(string $prefix = "")
    {
        try {
            $generator = ApplicationContext::getContainer()->get(IdGeneratorInterface::class);
            $id = $generator->generate();
        } catch (NotFoundExceptionInterface $e) {
            echo $e->getMessage();
            throw new BusinessException(ErrorCode::NORMAL_ERROR);
        } catch (ContainerExceptionInterface $e) {
            echo $e->getMessage();
            throw new BusinessException(ErrorCode::NORMAL_ERROR);
        } catch (\Throwable $exception) {
            echo $exception->getMessage();
            throw new BusinessException(ErrorCode::NORMAL_ERROR);
        }
        return $prefix . "" . date("Ym") . substr(strval($id), 8) . rand(10000000, 99999999);
    }


    /**
     * 商家订单回调处理
     * @param int $pay_order_id
     * @param string $pay_type
     * @param string $pay_method
     * @param string $outer_sn
     * @return int
     */
    public function orderNotifyPay(int $pay_order_id, string $pay_type, string $pay_method, string $outer_sn): int
    {
        return $this->getModelInstance()
            ->where(['pay_order_id' => $pay_order_id])
            ->update([
                'pay_type' => $pay_type,
                'pay_method' => $pay_method,
                'is_pay' => 1,
                'paid_price' => Db::raw('pay_price'),
                'paid_time' => time(),
                'pay_outer_sn' => $outer_sn,
                'order_status' => FlyOrderService::STATUS_WAIT_RECEIVE
            ]);
    }

    /**
     * 获取订单列表
     * @param $user_id
     * @param array $wheres
     * @return Builder
     */
    public function getOrderList($user_id, ?array $wheres): Builder
    {
        // 全部 - 未支付的、已支付的、已取消的、已完成的
        // 未支付 - 展示支付单信息
        // 已取消的 - 展示支付单信息

        // 已支付 - 展示店铺订单信息
        // 已完成的 - 展示店铺订单信息
        $wheres = empty($wheres) ? [] : $wheres;
        // 要展示支付单信息
        if (empty($wheres['status']) || in_array($wheres['status'], [self::STATUS_WAIT_PAY, self::STATUS_CLOSED])) {
            // 待支付 || 已取消
            $p_where = ['fly_order.is_pay' => 0, 'fly_order.user_id' => $user_id, 'fly_order.delete_time' => 0, 'fly_pay_order.delete_time' => 0];
            if (empty($wheres['status'])) {
                $status_field = Db::raw("ANY_VALUE(IF(wf_fly_pay_order.is_close=0,1,4)) as order_status");
            } else {
                if ($wheres['status'] == 1) {
                    $p_where['is_close'] = 0;
                } else {
                    $p_where['is_close'] = 1;// 已关闭的支付单
                }
                $status_field = Db::raw("ANY_VALUE(IF(" . $wheres['status'] . "=1,1,4)) as order_status");
            }

            $w_fields = [
                Db::raw("ANY_VALUE(wf_fly_pay_order.pay_order_id) as pay_order_id"),
                Db::raw("ANY_VALUE(wf_fly_pay_order.pay_order_sn) as pay_order_sn"),
                Db::raw("ANY_VALUE(wf_fly_order.order_sn) as order_sn"),
                Db::raw("ANY_VALUE(wf_fly_order.order_id) as order_id"),
                Db::raw("ANY_VALUE(GROUP_CONCAT(DISTINCT wf_fly_order.shop_name)) as shop_name"),
                Db::raw("ANY_VALUE(wf_fly_order.shop_id) as shop_id"), // 单店铺未支付订单有效
                Db::raw("ANY_VALUE(wf_fly_order.is_virtual) as is_virtual"),
                $status_field,
                Db::raw("ANY_VALUE(wf_fly_pay_order.delivery_type) as delivery_type"),
                Db::raw("ANY_VALUE(GROUP_CONCAT(wf_fly_order_product.sku_img)) as sku_img"),
                Db::raw("ANY_VALUE(CONCAT(wf_fly_order_product.product_name,wf_fly_order_product.sku_name)) as sku_name"),
                Db::raw("ANY_VALUE(sum(wf_fly_order_product.quantity)) as product_num"),
                Db::raw("ANY_VALUE(wf_fly_pay_order.order_style) as order_style"),
                Db::raw("ANY_VALUE(wf_fly_order.virtual_form_info) as virtual_form_info"),
                Db::raw("ANY_VALUE(wf_fly_order.create_time) as create_time"),
                Db::raw("ANY_VALUE(wf_fly_order.order_status) as o_order_status"),
                Db::raw("ANY_VALUE(wf_fly_pay_order.pay_price) as pay_price")];
            $pay_order = $this->flyPayOrder->getModelInstance()
                ->with(['with_products']) // 未支付没有售后单
                ->leftJoin('fly_order', 'fly_order.pay_order_id', '=', 'fly_pay_order.pay_order_id')
                ->leftJoin('fly_order_product', 'fly_order.order_id', '=', 'fly_order_product.order_id')
                ->where(function ($where) use ($wheres) {
                    if (!empty($wheres['keyword'])) {
                        $where->where('fly_order.order_sn', 'like', '%' . $wheres['keyword'] . '%')
                            ->orWhere('fly_order_product.product_name', 'like', '%' . $wheres['keyword'] . '%')
                            ->orWhere('fly_order.shop_name', 'like', '%' . $wheres['keyword'] . '%');
                    }
                })->where($p_where)
                ->groupBy(['fly_order.pay_order_id'])
                ->orderBy('o_order_status', 'asc')// 待付款-待收货-已完成-已关闭
                ->orderBy('create_time', 'desc')
                ->select($w_fields);
            // 包含已支付的订单
            if (empty($wheres['status'])) {
                // 已支付
                $o_fields = [
                    Db::raw("ANY_VALUE(wf_fly_order.order_id) as order_id"),
                    Db::raw("ANY_VALUE(wf_fly_order.pay_order_sn) as pay_order_sn"),
                    Db::raw("ANY_VALUE(wf_fly_order.order_sn) as order_sn"),
                    Db::raw("ANY_VALUE(wf_fly_order.pay_order_id) as pay_order_id"),
                    Db::raw("ANY_VALUE(wf_fly_order.shop_name) as shop_name"),
                    Db::raw("ANY_VALUE(wf_fly_order.shop_id) as shop_id"),
                    Db::raw("ANY_VALUE(wf_fly_order.is_virtual) as is_virtual"),
                    DB::raw("ANY_VALUE(wf_fly_order.order_status) as order_status"),
                    Db::raw("ANY_VALUE(wf_fly_order.delivery_type) as delivery_type"),
                    Db::raw("ANY_VALUE(GROUP_CONCAT(wf_fly_order_product.sku_img)) as sku_img"),
                    Db::raw("ANY_VALUE(CONCAT(wf_fly_order_product.product_name,wf_fly_order_product.sku_name)) as sku_name"),
                    Db::raw("ANY_VALUE(wf_fly_order.product_num) as product_num"),
                    Db::raw("ANY_VALUE(wf_fly_order.order_style) as order_style"),
                    Db::raw("ANY_VALUE(wf_fly_order.virtual_form_info) as virtual_form_info"),
                    Db::raw("ANY_VALUE(wf_fly_order.create_time) as create_time"),
                    Db::raw("ANY_VALUE(wf_fly_order.order_status) as o_order_status"),
                    Db::raw("ANY_VALUE(wf_fly_order.pay_price) as pay_price")];
                $paid_order = $this->getModelInstance()
                    ->with(['with_products', 'with_current_af', 'with_delivery_log', 'with_can_apply_af_products', 'with_can_apply_food_af_products'])
                    ->leftJoin('fly_order_product', 'fly_order.order_id', '=', 'fly_order_product.order_id')
                    ->where(function ($where) use ($wheres) {
                        if (!empty($wheres['keyword'])) {
                            $where->where('fly_order.order_sn', 'like', '%' . $wheres['keyword'] . '%')
                                ->orWhere('fly_order_product.product_name', 'like', '%' . $wheres['keyword'] . '%')
                                ->orWhere('fly_order.shop_name', 'like', '%' . $wheres['keyword'] . '%');
                        }
                    })
                    ->where(['fly_order.is_pay' => 1, 'fly_order.delete_time' => 0, 'fly_order.user_id' => $user_id])
                    ->groupBy(['fly_order.order_id'])
                    ->select($o_fields);
                return $paid_order->union($pay_order)
                    ->orderBy('o_order_status', 'asc')// 待付款-待收货-已完成-已关闭
                    ->orderBy('create_time', 'desc');//合并已支付的展示
            } else {
                return $pay_order;
            }
        } else {
            // 已支付
            $o_fields = [
                Db::raw('ANY_VALUE(wf_fly_order.order_id) as order_id'),
                Db::raw("ANY_VALUE(wf_fly_order.pay_order_sn) as pay_order_sn"),
                Db::raw("ANY_VALUE(wf_fly_order.order_sn) as order_sn"),
                Db::raw("ANY_VALUE(wf_fly_order.shop_name) as shop_name"),
                Db::raw("ANY_VALUE(wf_fly_order.shop_id) as shop_id"),
                Db::raw("ANY_VALUE(wf_fly_order.is_virtual) as is_virtual"),
                Db::raw("ANY_VALUE(wf_fly_order.order_status) as order_status"),
                Db::raw("ANY_VALUE(wf_fly_order.delivery_type) as delivery_type"),
                Db::raw("ANY_VALUE(GROUP_CONCAT(wf_fly_order_product.sku_img)) as sku_img"),
                Db::raw("ANY_VALUE(CONCAT(wf_fly_order_product.product_name,wf_fly_order_product.sku_name)) as sku_name"),
                Db::raw("ANY_VALUE(wf_fly_order.product_num) as product_num"),
                Db::raw("ANY_VALUE(wf_fly_order.order_style) as order_style"),
                Db::raw("ANY_VALUE(wf_fly_order.virtual_form_info) as virtual_form_info"),
                Db::raw("ANY_VALUE(wf_fly_order.create_time) as create_time"),
                Db::raw("ANY_VALUE(wf_fly_order.order_status) as o_order_status"),
                Db::raw("ANY_VALUE(wf_fly_order.pay_price) as pay_price")];
            return $this->getModelInstance()
                ->with(['with_products', 'with_current_af', 'with_delivery_log', 'with_can_apply_af_products', 'with_can_apply_food_af_products'])
                ->leftJoin('fly_order_product', 'fly_order.order_id', '=', 'fly_order_product.order_id')
                ->where(function ($where) use ($wheres) {
                    if (!empty($wheres['keyword'])) {
                        $where->where('fly_order.order_sn', 'like', '%' . $wheres['keyword'] . '%')
                            ->orWhere('fly_order_product.product_name', 'like', '%' . $wheres['keyword'] . '%')
                            ->orWhere('fly_order.shop_name', 'like', '%' . $wheres['keyword'] . '%');
                    }
                })->where(['fly_order.is_pay' => 1, 'fly_order.delete_time' => 0, 'fly_order.user_id' => $user_id, 'fly_order.order_status' => $wheres['status']])
                ->where(function ($where) use ($wheres) {
                    // 区分待使用和待收货
                    if ($wheres['status'] == self::STATUS_WAIT_RECEIVE) {
                        if (!empty($wheres['wait_use'])) {
                            $where->whereIn('order_style', [2, 3]);// 订座、点餐 待使用券码订单
                        } else {
                            $where->where('order_style', '=', 1); // 商城订单
                        }
                    }
                })
                ->groupBy(['fly_order.order_id'])
                ->orderBy('fly_order.order_status', 'asc')// 待付款-待收货-已完成-已关闭
                ->orderBy('fly_order.create_time', 'desc')
                ->select($o_fields);
        }
    }

    /**
     * 订单支付
     * @param array $params
     * @return false|string|Collection
     */
    public function payOrder(array $params)
    {
        $pay_service = $this->payService;
        // 支付参数验证
        $pay_v = $pay_service->payVerify($params);
        if (!$pay_v['res']) {
            throw new BusinessException(ErrorCode::NORMAL_ERROR, $pay_v['msg']);
        }
        return $pay_service->submit($pay_v['data']);
    }

    /**
     * 获取订单详情
     * @param int $user_id
     * @param int $order_id
     * @return array
     */
    public function getDetails(int $user_id, int $order_id): array
    {
        $my_order = $this->getModelInstance()
            ->with(['with_products', 'with_delivery_config', 'with_delivery_log', 'with_shop', 'with_current_af', 'with_can_apply_af_products', 'with_can_apply_food_af_products'])
            ->where('user_id', '=', $user_id)
            ->find($order_id);
        if (empty($my_order) || $my_order->delete_time != 0) {
            return [];
        }

        // 未支付的订单或已关闭的订单 要合并展示
        if ($my_order->is_pay == 0 || $my_order->order_status == self::STATUS_CLOSED) {
            $my_orders = $this->flyPayOrder->getPayOrderBySn($my_order->pay_order_sn);
            if (empty($my_order)) return [];
            $my_orders['order_status'] = $my_orders['is_close'] == 1 ? 4 : 1;
        } else {
            $my_orders = $my_order->toArray();
        }
        if (!empty($my_orders['with_can_apply_food_af_products'])) {
            unset($my_orders['with_can_apply_af_products']);
            $my_orders['with_can_apply_af_products'] = $my_orders['with_can_apply_food_af_products'];
        }
        if (isset($my_orders['with_delivery_log']['with_log']) && $my_orders['with_delivery_log']['with_log'] != '') {
            $my_orders['with_delivery_log']['with_log'][] = [
                "time" => $my_orders['with_delivery_log']['created_at'],
                "status_code" => -1,
                "status" => "发货",
            ];
            $my_orders['with_delivery_log']['with_log'][] = [
                "time" => date('Y-m-d H:i:s', $my_orders['paid_time']),
                "status_code" => -2,
                "status" => "下单",
            ];
        }
        if (!empty($my_orders['with_shop_order'])) {
            $my_orders['with_shop_order'][0]['virtual_form_info_arr'] = $arr = empty($my_orders['with_shop_order'][0]['virtual_form_info']) ? [] : json_decode($my_orders['with_shop_order'][0]['virtual_form_info'], true);
            // 订座订单商品名称
            if ($my_orders['order_style'] == 2) {
                $my_orders['with_shop_order'][0]['sku_name'] = date("m月d日,H:i", $arr['date_time']) . ',' . $arr['people_num'] . "人," . ($arr['is_vip'] ? "包间" : "大厅");
                $my_orders['with_shop_order'][0]['sku_img'] = $arr['logo'] ?? "";
            }
        } else {
            $my_orders['virtual_form_info_arr'] = $arr = empty($my_orders['virtual_form_info']) ? [] : json_decode($my_orders['virtual_form_info'], true);
            // 订座订单商品名称
            if ($my_orders['order_style'] == 2) {
                $my_orders['sku_name'] = date("m月d日,H:i", $arr['date_time']) . ',' . $arr['people_num'] . "人," . ($arr['is_vip'] ? "包间" : "大厅");
                $my_orders['sku_img'] = $arr['logo'] ?? "";
            }
        }
        if (empty($my_orders['address_id'])) {
            if (isset($my_orders['with_shop_order'][0]['address_id'])) {
                $my_orders['address_info'] = $this->address->getMyAddressById($user_id, $my_orders['with_shop_order'][0]['address_id']);
            } else {
                $my_orders['address_info'] = [];
            }
        } else {
            $my_orders['address_info'] = $this->address->getMyAddressById($user_id, $my_orders['address_id']);
        }
        return $my_orders ?? [];
    }

    /**
     * $order_id获取订单详情
     * @param int $order_id
     * @return array
     */
    public function getDetailsByOrderId(int $order_id): array
    {
        $my_order = $this->getModelInstance()
            ->with(['with_products', 'with_delivery_config', 'with_delivery_log', 'with_shop', 'with_current_af', 'with_can_apply_af_products', 'with_can_apply_food_af_products'])
            ->find($order_id);
        if (empty($my_order) || $my_order->delete_time != 0) {
            return [];
        }

        // 未支付的订单或已关闭的订单 要合并展示
        if ($my_order->is_pay == 0 || $my_order->order_status == self::STATUS_CLOSED) {
            $my_orders = $this->flyPayOrder->getPayOrderBySn($my_order->pay_order_sn);
            if (empty($my_order)) return [];
            $my_orders['order_status'] = $my_orders['is_close'] == 1 ? 4 : 1;
        } else {
            $my_orders = $my_order->toArray();
        }
        if (!empty($my_orders['with_can_apply_food_af_products'])) {
            unset($my_orders['with_can_apply_af_products']);
            $my_orders['with_can_apply_af_products'] = $my_orders['with_can_apply_food_af_products'];
        }
        if (isset($my_orders['with_delivery_log']['with_log']) && $my_orders['with_delivery_log']['with_log'] != '') {
            $my_orders['with_delivery_log']['with_log'][] = [
                "time" => $my_orders['with_delivery_log']['created_at'],
                "status_code" => -1,
                "status" => "发货",
            ];
            $my_orders['with_delivery_log']['with_log'][] = [
                "time" => date('Y-m-d H:i:s', $my_orders['paid_time']),
                "status_code" => -2,
                "status" => "下单",
            ];
        }
        if (!empty($my_orders['with_shop_order'])) {
            $my_orders['with_shop_order'][0]['virtual_form_info_arr'] = $arr = empty($my_orders['with_shop_order'][0]['virtual_form_info']) ? [] : json_decode($my_orders['with_shop_order'][0]['virtual_form_info'], true);
            // 订座订单商品名称
            if ($my_orders['order_style'] == 2) {
                $my_orders['with_shop_order'][0]['sku_name'] = date("m月d日,H:i", $arr['date_time']) . ',' . $arr['people_num'] . "人," . ($arr['is_vip'] ? "包间" : "大厅");
                $my_orders['with_shop_order'][0]['sku_img'] = $arr['logo'] ?? "";
            }
        } else {
            $my_orders['virtual_form_info_arr'] = $arr = empty($my_orders['virtual_form_info']) ? [] : json_decode($my_orders['virtual_form_info'], true);
            // 订座订单商品名称
            if ($my_orders['order_style'] == 2) {
                $my_orders['sku_name'] = date("m月d日,H:i", $arr['date_time']) . ',' . $arr['people_num'] . "人," . ($arr['is_vip'] ? "包间" : "大厅");
                $my_orders['sku_img'] = $arr['logo'] ?? "";
            }
        }
        if (empty($my_orders['address_id'])) {
            if (isset($my_orders['with_shop_order'][0]['address_id'])) {
                $my_orders['address_info'] = $this->address->getMyAddressById(intval($my_order['user_id']), $my_orders['with_shop_order'][0]['address_id']);
            } else {
                $my_orders['address_info'] = [];
            }
        } else {
            $my_orders['address_info'] = $this->address->getMyAddressById(intval($my_order['user_id']), $my_orders['address_id']);
        }
        return $my_orders ?? [];
    }

    /**
     * 关闭取消订单
     * @param int $user_id
     * @param string $pay_order_sn
     * @param int $cancel_reason
     * @param int $return_cart
     * @return bool
     */
    public function cancelOrder(int $user_id, string $pay_order_sn, int $cancel_reason, int $return_cart): bool
    {
        if (empty($user_id) || empty($pay_order_sn)
            || empty($cancel_reason)
        ) {
            return false;
        }
        $pay_order = $this->flyPayOrder->getPayOrderBySn($pay_order_sn);
        if (empty($pay_order) || $pay_order['user_id'] != $user_id) {
            throw new BusinessException(ErrorCode::NORMAL_ERROR, '订单不存在');
        }
        // 取消原因
        $style = $pay_order['with_shop_order'][0]['order_style'] ?? 1;
        // 取消原因
        $reason_style = $style == self::STYLE_SEAT ? AftersaleSetService::MODEL_TYPE_FOOD_SEAT : ($style == self::STYLE_ORDER ? AftersaleSetService::MODEL_TYPE_FOOD_ORDER : AftersaleSetService::MODEL_TYPE_SHOP);
        $reason = $this->reasonSet->getOrderReasonByID($cancel_reason, AftersaleSetService::TYPE_ORDER_CANCEL, $reason_style);
        if (empty($reason)) {
            throw new BusinessException(ErrorCode::NORMAL_ERROR, '取消失败1');
        }
        try {
            // 关闭支付单
            $this->flyPayOrder->closePayOrder($pay_order_sn, $user_id, (int)$reason['id'], $reason['name']);
            // 关闭商家订单
            $this->getModelInstance()
                ->where(['pay_order_sn' => $pay_order_sn, 'is_pay' => 0, 'user_id' => $user_id, 'order_status' => self::STATUS_WAIT_PAY])
                ->update(['order_status' => self::STATUS_CLOSED, 'close_time' => time(), 'cancel_reason' => $reason['name']]);
            // 是否使用优惠券：适用优惠券、返还优惠券
            foreach ($pay_order['with_shop_order'] as $shop_order) {
                if ($shop_order['coupon_id'] > 0) {
                    if (!$this->orderCoupon->backUserCoupon($user_id, $shop_order['coupon_id'])) {
                        throw new BusinessException(ErrorCode::NORMAL_ERROR, '优惠券返还失败');
                    }
                }
            }

            // 是否重新加入购物车
            if (!empty($return_cart)) {
                // 重新加入购物车
                $carts = [];
                foreach ($pay_order['with_products'] as $with_product) {
                    $carts[] = ['sku_id' => $with_product['sku_id'], 'quantity' => $with_product['quantity'], 'is_selected' => 1];
                }
                $this->cart->cartAdd(['user_id' => $user_id, 'carts' => $carts]);
            }
        } catch (\Throwable $exception) {
            echo $exception->getMessage();
            throw new BusinessException(ErrorCode::NORMAL_ERROR, 'error');
        }
        return true;
    }

    /**
     * 删除订单
     * @param string $pay_order_sn
     * @param int $user_id
     * @return bool
     */
    public function deleteOrder(string $pay_order_sn, int $user_id): bool
    {
        $pay = $this->flyPayOrder->getModelInstance()
            ->where(['user_id' => $user_id, 'pay_order_sn' => $pay_order_sn])
            ->first();
        // 已支付||未关闭||已删除
        if (empty($pay) || $pay->is_pay == 1 || $pay->is_close == 0 || $pay->delete_time > 0) {
            throw new BusinessException(ErrorCode::NORMAL_ERROR, '删除失败，状态错误');
        }
        try {
            $this->flyPayOrder->getModelInstance()
                ->where(['pay_order_sn' => $pay_order_sn])
                ->update(['delete_time' => time()]);
            $this->getModelInstance()
                ->where(['pay_order_sn' => $pay_order_sn, 'order_status' => 1, 'is_pay' => 0, 'user_id' => $user_id])
                ->update(['delete_time' => time()]);
        } catch (\Throwable $exception) {
            throw new BusinessException(ErrorCode::NORMAL_ERROR, '删除失败');
        }
        return true;
    }

    /**
     * 签收订单 配送单|快递单|
     * @param int $user_id
     * @param string $order_sn
     * @return bool
     */
    public function receive(int $user_id, string $order_sn): bool
    {
        $instance = $this->getModelInstance()
            ->where('user_id', '=', $user_id)
            ->where('order_sn', '=', $order_sn)
            ->first();
        if (empty($instance) || empty($instance->toArray()) || $instance->is_received != 0 || $instance->order_status != self::STATUS_WAIT_RECEIVE) {
            throw new BusinessException(ErrorCode::NORMAL_ERROR, '签收失败');
        }
        if ($instance->delivery_type == ShopDeliveryConfigService::TYPE_OWN) {
            $instance->charge_type = 3;
        }
        $instance->is_received = 1;
        $instance->order_status = self::STATUS_FINISHED;
        $instance->received_time = time();
        return $instance->save();
    }

    /**
     * 获取曾经购买过商品列表
     * @param int $user_id
     * @param int $shop_id
     * @param int $order_style
     */
    public function getHasBuy(int $user_id, int $shop_id, int $order_style)
    {
        var_dump($order_style);
        var_dump($user_id);
        var_dump($shop_id);

        $fields = [
            Db::raw("ANY_VALUE(wf_fly_order_product.product_id) as product_id"),
            Db::raw("ANY_VALUE(wf_fly_order.paid_time) as paid_time")
        ];

        return make(FlyOrderProduct::class)
            ->with(['with_product'])
            ->has('with_product')
            ->leftJoin('fly_order', 'fly_order_product.order_id', 'fly_order.order_id')
            ->leftJoin('fly_sku', 'fly_order_product.sku_id', '=', 'fly_sku.sku_id')
            ->where(function ($where) use ($user_id, $shop_id, $order_style) {
                $where->where('is_pay', '=', 1)
                    ->where('fly_order.user_id', '=', $user_id)
                    ->where('fly_order.order_style', '=', $order_style)
                    ->where('fly_order.shop_id', '=', $shop_id);
            })
            ->groupBy(['fly_order_product.product_id'])
            ->orderBy('paid_time', 'desc')
            ->select($fields);
    }


    /**
     * 获取订单模型
     * @return mixed
     */
    public function getInstance()
    {
        return $this->getModelInstance();
    }
}